#include "microhost.h"
#include "free-cube/aplugin.h"
#include "free-cube/adriver.h"
#include "drivers/driverjack.h"
//#include "transport.h"
#include "refreshtimer.h"
#include "free-cube/logger.h"
#include "free-cube/freecube.h"
#include "free-cube/time.h"

#include "clock.h"
#include "statusbarcontrols.h"
#include <QStatusBar>

#include "mainwindow.h"
#include "pluginrack.h"

#include "dummysequenser.h"

#define TIMOUT 100

using namespace fc;
MicroHost::MicroHost() :
  is_stopped_(true),
  timer_ (new RefreshTimer()),
  main_window_ (new MainWindow),
  sequencer_ (new DummySequenser()),
  clock_ (new Clock()),
  rack_ (new PluginRack)
{
  StatusBarControls * status = new StatusBarControls();
  status->set_model( *sequencer_ );
  timer_->submit( status );
  main_window_->statusBar()->addPermanentWidget(status);
}

Buffer MicroHost::buffer_;

MicroHost::~MicroHost(){
  log("MH: ... shutting down ");
  shutdown();
  log("MH: ... quitting ");
}

bool MicroHost::init(){
  set_driver(QSharedPointer<ADriver> (new DriverJack("Metronome")));
  driver_->init(*this);
  buffer_ = Buffer (2, 2, driver_->buffer_size());
  driver_->set_buffer(buffer_);

  sequencer_->set_clock(clock_);
  sequencer_->set_samplerate(driver_->sample_rate());

  driver_->start();
  timer_->start_timer();
  is_stopped_ = false;
  return true;
};

void MicroHost::shutdown(){
  timer_->stop_timer();
  is_stopped_ = true;
  fc::msec_sleep(TIMOUT);
  driver_->stop();
  main_window_->close();
};

void MicroHost::load_plugin(APlugin & plugin){
  is_stopped_ = true;
  fc::msec_sleep(TIMOUT);
  plugin.set_master_handler(*this);
  rack_->load(plugin);
  is_stopped_ = false;
}

void MicroHost::set_driver(QSharedPointer<ADriver> driver) {
  driver_ = QSharedPointer<ADriver> (driver);
}

void MicroHost::show() {
  main_window_->show();
}

void MicroHost::show_driver_panel() {
}

void MicroHost::process(){
  if (is_stopped_) return;
  sequencer_-> set_size_to_process(buffer_.size());

  TimeT size;
  while (0 < (size = sequencer_->process_frames())){
    if (is_stopped_) break;
    rack_->process(size);
    clock_->process(size);
  }
}

void MicroHost::sample_rate_changed(){}
void MicroHost::buffer_size_changed(){}
void MicroHost::connection_changed(){}

void MicroHost::connect_plugins_data(int out, int in){
  rack_->connect_data(out, in);
}

